﻿namespace com.u3d.bases.controller
{
    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    using UnityEngine;

    public class CDConroller
    {
        private Dictionary<CDPriority, Dictionary<int, CDTimeVo>> _cdPriDic = new Dictionary<CDPriority, Dictionary<int, CDTimeVo>>();
        private Dictionary<int, CDTimeVo> _realCDDic = new Dictionary<int, CDTimeVo>();
        private List<KeyValuePair<CDPriority, int>> _removeCdList = new List<KeyValuePair<CDPriority, int>>();
        private List<int> _skillTypeList = new List<int>();

        public CDConroller()
        {
            this.Init();
        }

        public void AddNormalSkillCd(int skillType, float TotalTime, bool needCover, CDEndCallBack callBack = null)
        {
            CDTimeVo cdVo = new CDTimeVo {
                skillType = skillType,
                totalCd = TotalTime,
                callBack = callBack,
                showMask = true,
                priority = CDPriority.Third
            };
            this.AddSkillCdVo(skillType, cdVo, CDPriority.Third, needCover);
            this.InitRealDicAndTypeList(skillType);
        }

        public void AddPrioritySkillCd(int skillType, float TotalTime, bool showMask, CDPriority priority, CDEndCallBack callBack = null)
        {
            CDTimeVo cdVo = new CDTimeVo {
                skillType = skillType,
                currentCd = TotalTime,
                totalCd = TotalTime,
                callBack = callBack,
                showMask = showMask,
                priority = priority
            };
            this.AddSkillCdVo(skillType, cdVo, priority, false);
        }

        private void AddSkillCdVo(int skillType, CDTimeVo cdVo, CDPriority priority, bool needCover = false)
        {
            if (!this._cdPriDic.ContainsKey(priority))
            {
                this._cdPriDic[priority] = new Dictionary<int, CDTimeVo>();
            }
            if (needCover || !this._cdPriDic[priority].ContainsKey(skillType))
            {
                this._cdPriDic[priority][skillType] = cdVo;
            }
        }

        public void ClearPriorityCdByType(int skillType, CDPriority priority)
        {
            this._cdPriDic[priority][skillType].currentCd = 0f;
            this._cdPriDic[priority].Remove(skillType);
        }

        private void DoCdUpdate(float delTime)
        {
            foreach (KeyValuePair<CDPriority, Dictionary<int, CDTimeVo>> pair in this._cdPriDic)
            {
                foreach (KeyValuePair<int, CDTimeVo> pair2 in pair.Value)
                {
                    if (pair2.Value.currentCd >= 0f)
                    {
                        CDTimeVo local1 = pair2.Value;
                        local1.currentCd -= Time.deltaTime;
                        if (pair2.Value.currentCd <= 0f)
                        {
                            if (pair2.Value.callBack != null)
                            {
                                pair2.Value.callBack();
                            }
                            if (pair2.Value.publicCd != 0f)
                            {
                                pair2.Value.publicCd = 0f;
                            }
                            if (((CDPriority) pair.Key) != CDPriority.Third)
                            {
                                this._removeCdList.Add(new KeyValuePair<CDPriority, int>(pair.Key, pair2.Key));
                            }
                        }
                    }
                }
            }
        }

        public CDTimeVo GetCurrentCdTimeVo(int skillType)
        {
            if (this._cdPriDic[CDPriority.First].ContainsKey(skillType))
            {
                return this._cdPriDic[1][skillType];
            }
            if (this._cdPriDic[CDPriority.Second].ContainsKey(skillType))
            {
                return this._cdPriDic[2][skillType];
            }
            if (this._cdPriDic[CDPriority.Third].ContainsKey(skillType))
            {
                return this._cdPriDic[3][skillType];
            }
            return null;
        }

        public Dictionary<int, CDTimeVo> GetRealCdDic()
        {
            foreach (int num in this._skillTypeList)
            {
                this._realCDDic[num] = this.GetCurrentCdTimeVo(num);
            }
            return this._realCDDic;
        }

        private void Init()
        {
            this._cdPriDic.Add(CDPriority.First, new Dictionary<int, CDTimeVo>());
            this._cdPriDic.Add(CDPriority.Second, new Dictionary<int, CDTimeVo>());
            this._cdPriDic.Add(CDPriority.Third, new Dictionary<int, CDTimeVo>());
        }

        private void InitRealDicAndTypeList(int skillType)
        {
            if (!this._realCDDic.ContainsKey(skillType))
            {
                this._realCDDic.Add(skillType, null);
            }
            if (!this._skillTypeList.Contains(skillType))
            {
                this._skillTypeList.Add(skillType);
            }
        }

        private void RemovePriorityCd()
        {
            foreach (KeyValuePair<CDPriority, int> pair in this._removeCdList)
            {
                this._cdPriDic[pair.Key].Remove(pair.Value);
            }
            this._removeCdList.Clear();
        }

        public void Reset()
        {
            this._realCDDic.Clear();
            this._removeCdList.Clear();
            this._skillTypeList.Clear();
            this._cdPriDic.Clear();
        }

        public void Update()
        {
            this.DoCdUpdate(Time.deltaTime);
            if (this._removeCdList.Count > 0)
            {
                this.RemovePriorityCd();
            }
        }

        public void UpdateNormalSkillCd(int skillType)
        {
            if (!this._cdPriDic[CDPriority.Third].ContainsKey(skillType))
            {
                Debug.LogError("技能CD没有初始化:" + skillType);
            }
            else
            {
                this._cdPriDic[3][skillType].ResetCurrnetCd();
            }
        }

        public void UpdatePublicCd(int skillType, float cd)
        {
            if (this._cdPriDic[CDPriority.Third].ContainsKey(skillType))
            {
                this._cdPriDic[3][skillType].SetPublicCd(cd);
            }
        }
    }
}

